package com.gimi.cloud.bbp.manage.service.sys.impl;

import com.gimi.cloud.bbp.common.enums.ResponseCodeEnum;
import com.gimi.cloud.bbp.common.exception.MsgException;
import com.gimi.cloud.bbp.common.utils.ReflectUtils;
import com.gimi.cloud.bbp.common.utils.StringUtil;
import com.gimi.cloud.bbp.dao.dao.sys.SysMasterDao;
import com.gimi.cloud.bbp.dao.dao.sys.SysMenuDao;
import com.gimi.cloud.bbp.dao.myMapper.core.query.QueryParam;
import com.gimi.cloud.bbp.dto.sys.SysMenuDTO;
import com.gimi.cloud.bbp.entity.sys.SysMasterEntity;
import com.gimi.cloud.bbp.entity.sys.SysMenuEntity;
import com.gimi.cloud.bbp.manage.service.sys.SysMenuService;
import com.github.pagehelper.PageHelper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 系统菜单相关接口实现类
 *
 * @author wbj
 * @version 1.0
 * @Description
 * @create 2018-01-24
 **/
@Service
public class SysMenuServiceImpl implements SysMenuService{
    private static final Logger logger = LoggerFactory.getLogger(SysMenuServiceImpl.class);
    private SysMenuDao sysMenuDao;
    private SysMasterDao sysMasterDao;

    @Autowired
    public SysMenuServiceImpl(SysMenuDao sysMenuDao, SysMasterDao sysMasterDao) {
        this.sysMenuDao = sysMenuDao;
        this.sysMasterDao = sysMasterDao;
    }

    @Override
    public List<SysMenuDTO> queryList(SysMenuDTO dto, boolean isPaging) throws Exception {
        if(isPaging){
            PageHelper.startPage(dto.getPageNums(),dto.getPageSizes());
        }
        String sql ="SELECT menu.*,pme.me_name me_pname" +
                " FROM sys_menu menu" +
                " LEFT JOIN sys_menu pme ON pme.is_delete = 0 AND menu.me_pid = pme.me_id" +
                " WHERE menu.is_delete = 0 " +
                " ORDER BY menu.me_order";
        QueryParam param = new QueryParam();
        param.setSql(sql);
        param.setParamObject(dto);
        return sysMenuDao.selectListDTOBySql(param);
    }

    @Override
    public SysMenuDTO load(SysMenuDTO dto, Object id) throws Exception {
        SysMenuEntity menu = sysMenuDao.queryBy("me_id", id);
        if (null == menu) {
            return null;
        }
        SysMenuDTO sysMenuDto = new SysMenuDTO();
        ReflectUtils.copyPropertiesIgnoreNull(menu, sysMenuDto);
        return sysMenuDto;
    }

    @Override
    public SysMenuDTO saveOrUpdate(SysMenuDTO dto) throws Exception {
        SysMenuEntity menu = null;
        if (null != dto.getMeId()) {
            menu = sysMenuDao.queryBy("me_id", dto.getMeId());
            if (null == menu) {
                throw new MsgException(ResponseCodeEnum.PARAMETER_EXCEPTION,"未获取到主键为" + dto.getMeId() + "的菜单信息,保存失败");
            }
        } else {
            menu = new SysMenuEntity();
        }
        ReflectUtils.copyPropertiesIgnoreNull(dto, menu);
        if(StringUtils.isNotBlank(menu.getMePermission())){
            int existCount = 0;
            if(null == menu.getMeId()){
                existCount = sysMenuDao.queryCountBy("me_permission", menu.getMePermission());
            }else{
                existCount = sysMenuDao.queryCountByExclude("me_permission", menu.getMePermission(), "me_id", dto.getMeId());
            }
            if(existCount>0){
                throw new MsgException(ResponseCodeEnum.ERR_USERNAME_USED,"已存在菜单权限为"+menu.getMePermission()+"菜单");
            }
        }
        if (null != dto.getMeId()) {
            sysMenuDao.baseUpdateByPrimaryKey(menu);
        } else {
            sysMenuDao.baseInsert(menu);
        }
        ReflectUtils.copyPropertiesIgnoreNull(menu, dto);
        return dto;
    }

    @Override
    public int delete(SysMenuDTO dto, Object id, boolean realDel) throws Exception {
        SysMenuEntity menu = sysMenuDao.queryBy("me_id", id);
        if (null == menu) {
            throw new MsgException(ResponseCodeEnum.NO_DATA,"未获取主键为" + id + "的菜单信息，删除失败");
        }
        Integer count = sysMenuDao.queryCountBy("me_pid", id);
        if(count > 0){
            throw new MsgException(ResponseCodeEnum.ERR_USERNAME_USED,"当前菜单下存在子菜单，不允许删除");
        }
        //非物理删除
        if (!realDel) {
            ReflectUtils.copyPropertiesIgnoreNullAndEmptyStr(dto, menu);
            menu.setIsDelete(1);
            return sysMenuDao.baseUpdateByPrimaryKey(menu);
        }
        return sysMenuDao.deleteByPrimaryKey(id);
    }

    @Override
    public List<SysMenuDTO> menuToTree(List<SysMenuDTO> menuDTOS) throws Exception {
        List<SysMenuDTO> result = new LinkedList<>();
        for (SysMenuDTO sysMenuDto : menuDTOS) {
            if (null != sysMenuDto.getMePid() && 0 == sysMenuDto.getMePid()) {
                initChild(sysMenuDto, menuDTOS);
                result.add(sysMenuDto);
            }
        }
        return result;
    }

    /**
     * 初始化孩子节点
     * @param dto 父菜单
     * @param sysMenuDtos 所有菜单信息
     */
    private void initChild(SysMenuDTO dto, List<SysMenuDTO> sysMenuDtos) {
        List<SysMenuDTO>  childs = null;
        if (null == dto.getChilds()) {
            childs = new LinkedList<>();
        }
        for (SysMenuDTO sysMenuDto : sysMenuDtos) {
            if (sysMenuDto.getMePid().equals(dto.getMeId())) {
                childs.add(sysMenuDto);
                dto.setChilds(childs);
            }
        }
        if(childs != null && childs.size() > 0){
            for(SysMenuDTO menu:childs){
                initChild(menu, sysMenuDtos);
            }
        }
    }
    @Override
    public List<SysMenuDTO> getMenuByMasterId(SysMenuDTO dto, Integer maId) throws Exception {
        SysMasterEntity master = sysMasterDao.queryBy("ma_id",maId);
        if(null == master){
            return null;
        }
        //避免异常数据产生,如果标识为null，则默认为普通用户
        Integer masterIsAdmin = null == master.getMaIsadmin() ? 0: master.getMaIsadmin();
        String sql = "";
        //普通管理员
        switch (masterIsAdmin){
            case -1:
                //超级管理员查看未删除的菜单
                sql = "SELECT menu.* FROM sys_menu menu where menu.is_delete = 0 order BY me_order";
                break;
            case 1:
                //系统管理员查看未删除，且状态为启用的菜单
                sql = "SELECT menu.* FROM sys_menu menu where menu.is_delete = 0 and menu.me_status = 1 order BY me_order";
                break;
            default:
                //普通管理员只查看属于自己的菜单
                sql = "SELECT menu.*" +
                    " FROM sys_menu menu" +
                    " LEFT JOIN sys_authority auth ON menu.me_id = auth.me_id" +
                    " LEFT JOIN sys_role role ON role.is_delete = 0 AND role.ro_id = auth.ro_id" +
                    " LEFT JOIN sys_master_role mr ON mr.ro_id = role.ro_id" +
                    " WHERE menu.is_delete = 0 and menu.me_status = 1 and mr.ma_id = " + maId +
                    " GROUP BY menu.me_id" +
                    " ORDER BY menu.me_order";
                break;
        }
        QueryParam queryParam = new QueryParam();
        queryParam.setSql(sql);
        queryParam.setParamObject(null);
        return sysMenuDao.selectListDTOBySql(queryParam);
    }

    @Override
    public Map<String, Object> getPermissions(SysMenuDTO dto, List<SysMenuDTO> menus) throws Exception {
        Map<String,Object> result = new HashMap<>();
        List<String> permissions = new ArrayList<>();
        List<String> serviceNames = new ArrayList<>();
        for(SysMenuDTO menu:menus){
            if(StringUtil.isNotBlank(menu.getMeServiceName())){
                serviceNames.add(menu.getMeServiceName());
            }
            if(StringUtil.isNotBlank(menu.getMePermission())){
                permissions.add(menu.getMePermission());
            }
        }
        result.put("permissions",permissions);
        result.put("serviceNames",serviceNames);
        return result;
    }

    @Override
    public List<SysMenuDTO> getMenuByRoId(SysMenuDTO dto, Integer roId) throws Exception {
        if(null == roId){
            return null;
        }
        String sql ="SELECT menu.*,(SELECT count(*) FROM sys_authority WHERE me_id = menu.me_id  AND ro_id = "+roId+") has_auth" +
            " FROM sys_menu menu" +
            " WHERE menu.is_delete = 0 AND menu.me_status = 1" +
            " ORDER BY menu.me_order";
        QueryParam queryParam = new QueryParam();
        queryParam.setSql(sql);
        queryParam.setParamObject(null);
        return sysMenuDao.selectListDTOBySql(queryParam);
    }
}
